﻿using System;
using System.Reflection;
using System.IO;
using System.Data;
using System.Windows.Forms;

namespace WinFormClient
{
   public delegate void Update(bool complete);
    public class Build
    {
        private static ColumnMapCollection ColumnsMap(DataRow[] columns)
        {
            ColumnMapCollection col = new ColumnMapCollection();
            foreach (DataRow tr in columns)
            {
                if (Boolean.Parse(tr[Columns.COLUMN_Choose].ToString()))
                {
                    col.Add(
                        tr[Columns.COLUMN_ColumnName].ToString(),
                        tr[Columns.COLUMN_DbDataType].ToString(),
                        Tools.FieldConvert(tr[Columns.COLUMN_PropertyName].ToString()),
                        tr[Columns.COLUMN_PropertyType].ToString(),
                        int.Parse(tr[Columns.COLUMN_DbDataLength].ToString()),
                        tr[Columns.COLUMN_ResourceValue].ToString(),
                        tr[Columns.COLUMN_IndexName].ToString(),
                        tr[Columns.COLUMN_DbDefaultValue].ToString(),
                        int.Parse(tr[Columns.COLUMN_VisibleIndex].ToString()),
                        tr[Columns.COLUMN_Visibility].ToString(),
                        tr[Columns.COLUMN_Editable].ToString(),
                        tr[Columns.COLUMN_DevControl].ToString(),
                        tr[Columns.COLUMN_Spin].ToString(),
                        tr[Columns.COLUMN_PropertyName].ToString(),
                        bool.Parse(tr[Columns.COLUMN_NotNull].ToString())
                        );
                }
            }
            return col;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="nameSpace">类名</param>
        /// <param name="sequence">为了产生一个ID</param>
        /// <param name="db">？？</param>
        /// <param name="oracleObjects">表</param>
        /// <param name="oracleColumns">字段</param>
        /// <param name="xmlFolder">路径</param>
        /// <param name="classFolder">路径</param>
        public static void Execute(string nameSpace,string sequence, IDataBase db,DataTable oracleObjects,DataTable oracleColumns,string xmlFolder,string classFolder)
        {
            MapXml.Reset();
            MapXml.DataBase = db;
            MapXml.NameSpace = String.IsNullOrEmpty(nameSpace)?"TEMP.DATA":nameSpace;
            MapXml.Sequence = String.IsNullOrEmpty(sequence) ? MapXml.NameSpace + "_Sequence" : sequence;

            foreach (DataRow dr in oracleObjects.Rows)
            {
                if (Boolean.Parse(dr[Columns.OBJECT_Choose].ToString()))
                {
                    
                    string table = dr[Columns.OBJECT_DataName].ToString(); //得到Table名 
                    ColumnMapCollection col = ColumnsMap(oracleColumns.Select(Columns.COLUMN_DataName + "='" + table + "'")); //找到这个Table的所有字段
                    MapXml xml = new MapXml(table, dr[Columns.OBJECT_ClassName].ToString(), col); //实例化一个XML类
                    xml.Builder(true,true,true,true,true,true,true,true,true,true,true); //构建XML文件
                    //bar.Invoke(update,false);
                    MethodCollection mtds = xml.Methods;
                    table = dr[Columns.OBJECT_ClassName].ToString();
                    new Dao(table, mtds).Builder();
                    //bar.Invoke(update, false);
                    new DaoInterface(table, mtds).Builder();
                    //bar.Invoke(update,false);
                    new DataObjectEntry(table,dr[Columns.OBJECT_Interface].ToString(), col).Builder();
                    //bar.Invoke(update, false);
                    new DataObjectParameters(table, col).Builder();
                    //bar.Invoke(update, false);
                    new Service(table, mtds).Builder();
                    //bar.Invoke(update, false);
                    xml.Dispose();
                }
            }
            Assembly asly = db.GetType().Assembly;
            Include(asly, db, nameSpace);
            //bar.Invoke(update, false);
            string basePath = System.AppDomain.CurrentDomain.BaseDirectory + "\\Result";

            CopyFolder(basePath + "\\Xml\\Oracle", xmlFolder);
            //bar.Invoke(update, false);

            CopyFolder(basePath + "\\Dao", classFolder + "\\Dao");
            //bar.Invoke(update, false);

            CopyFolder(basePath + "\\Interface", classFolder + "\\Interface");
            //bar.Invoke(update, false);

            CopyFolder(basePath + "\\Model", classFolder + "\\Model");
            //bar.Invoke(update, false);

            CopyFolder(basePath + "\\Parameters", classFolder + "\\Parameters");
            //bar.Invoke(update, false);

            CopyFolder(basePath + "\\Service", classFolder + "\\Service");

            //bar.Invoke(update, true);
        }

        private static void CopyFolder(string sourceFolder,string targetFolder)
        {
            if (!System.IO.Directory.Exists(sourceFolder)) return;
            if (!System.IO.Directory.Exists(targetFolder)) return;
            try
            {
                string[] files = System.IO.Directory.GetFiles(sourceFolder);
                foreach (string file in files) System.IO.File.Copy(file, targetFolder + "\\" + System.IO.Path.GetFileName(file), true);
            }
            catch
            { }
        }

        private static string ResourceContent(string resourceName,Assembly asly)
        {
            Stream str = asly.GetManifestResourceStream(resourceName);
            StreamReader sr = new StreamReader(str);
            string content = sr.ReadToEnd();
            sr.Close();
            str.Dispose();

            return content;
        }

        private static void Include(Assembly asly, IDataBase db, string nameSpace)
        {
            //Tools.WriteContentToTextFile(ResourceContent("WAF.iBatisBuilder.Include.Core.Attributes.cs", asly), "\\Result\\Core\\Attributes.cs", "$NameSpace$", MapXml.NameSpace);
            Tools.WriteContentToTextFile(ResourceContent("WAF.iBatisBuilder.Include.Core.DaoLoader.cs", asly), "\\Result\\Core\\DaoLoader.cs", "$NameSpace$", MapXml.NameSpace);
            Tools.WriteContentToTextFile(ResourceContent("WAF.iBatisBuilder.Include.Core.ObjectBase.cs", asly), "\\Result\\Core\\ObjectBase.cs", "$NameSpace$", MapXml.NameSpace);
            //Tools.WriteContentToTextFile(ResourceContent("WAF.iBatisBuilder.Include.Core.IModel.cs", asly), "\\Result\\Core\\IModel.cs", "$NameSpace$", MapXml.NameSpace);

            Tools.WriteContentToTextFile(ResourceContent("WAF.iBatisBuilder.Include.Dao.config", asly).Replace("$DataBaseProvider$", db.PRIVATE).Replace("$ConnectionString$", db.ConnectionString), "\\Result\\Dao.config", "$DaoFactory$", MapXml.DaoFactory);
            Tools.WriteContentToTextFile(ResourceContent("WAF.iBatisBuilder.Include.SqlMap.config", asly), "\\Result\\SqlMap.config", "$SqlMaps$", MapXml.SqlMaps);
            Tools.WriteContentToTextFile(ResourceContent("WAF.iBatisBuilder.Include.providers.config", asly), "\\Result\\providers.config", null, null);

            Tools.WriteContentToTextFile(ResourceContent("WAF.iBatisBuilder.Include.Temp.csproj", asly), "\\Result\\" + nameSpace + ".csproj", "$NameSpace$", nameSpace);
            Tools.WriteContentToTextFile(ResourceContent("WAF.iBatisBuilder.Include.Temp.csproj.user", asly), "\\Result\\" + nameSpace + ".csproj.user", null, null);
            
            Tools.SaveFile(asly.GetManifestResourceStream("WAF.iBatisBuilder.Include.ExtraBin.IBatisNet.Common.dll"), "\\Result\\ExtraBin\\IBatisNet.Common.dll");
            Tools.SaveFile(asly.GetManifestResourceStream("WAF.iBatisBuilder.Include.ExtraBin.IBatisNet.DataAccess.dll"), "\\Result\\ExtraBin\\IBatisNet.DataAccess.dll");
            Tools.SaveFile(asly.GetManifestResourceStream("WAF.iBatisBuilder.Include.ExtraBin.IBatisNet.DataMapper.dll"), "\\Result\\ExtraBin\\IBatisNet.DataMapper.dll");
            Tools.SaveFile(asly.GetManifestResourceStream("WAF.iBatisBuilder.Include.ExtraBin.Castle.DynamicProxy.dll"), "\\Result\\ExtraBin\\Castle.DynamicProxy.dll"); 
        }
    }
}
